import logging
from datetime import date, timedelta
from decimal import Decimal
from typing import Any, Literal, LiteralString

from auditlog.models import AuditlogHistoryField
from auditlog.registry import auditlog
from django.contrib import admin
from django.core.validators import MaxValueValidator, MinValueValidator
from django.db import models
from django.db.models import F
from django.utils import timezone
from django.utils.html import format_html
from django.utils.safestring import SafeText

from customauth.models import MyUser

# Create your models here.


class Base(models.Model):
    create_at = models.DateTimeField(default=timezone.now)
    update_at = models.DateTimeField(auto_now=True)
    history = AuditlogHistoryField()

    class Meta:
        abstract = True


class Spr_opl(Base):  # noqa: N801
    opl = models.PositiveIntegerField(
        blank=False,
        null=False,
        unique=True,
        validators=[MinValueValidator(0), MaxValueValidator(99)],
    )
    name_opl = models.CharField(max_length=100, blank=False, null=False)

    class Meta:
        verbose_name = "Справочник оплаты"
        verbose_name_plural = "Справочник оплаты"

    def __str__(self) -> str:
        return f"{self.opl} {self.name_opl}"


class Spr_sdl(Base):  # noqa: N801
    sdl = models.PositiveIntegerField(blank=False, null=False, unique=True)
    name_sdl = models.CharField(max_length=100, blank=True, null=False)

    class Meta:
        verbose_name = "Справочник должностей"
        verbose_name_plural = "Справочник должностей"

    def __str__(self) -> str:
        return f"{self.sdl} {self.name_sdl}"


class Spr_lab(Base):  # noqa: N801
    lab = models.PositiveIntegerField(blank=False, null=False)
    name_lab = models.CharField(max_length=100, blank=False, null=False)

    class Meta:
        verbose_name = "Справочник лабораторий"
        verbose_name_plural = "Справочник лабораторий"

    def __str__(self) -> str:
        return f"{self.lab} {self.name_lab}"


class Spr_lpu(Base):  # noqa: N801
    lpu = models.PositiveIntegerField(blank=False, null=False, unique=True)
    name_lpu = models.CharField(max_length=100, blank=False, null=False)
    adress = models.CharField(max_length=100, blank=True, null=False)

    class Meta:
        verbose_name = "Справочник ЛПУ"
        verbose_name_plural = "Справочник ЛПУ"

    def __str__(self) -> str:
        return f"{self.lpu} {self.name_lpu}"


class Sdl_set(Base):  # noqa: N801
    doc = models.IntegerField(
        blank=False,
        null=False,
        validators=[MinValueValidator(0), MaxValueValidator(9999999)],
    )
    tech = models.IntegerField(
        blank=False,
        default=0,
        validators=[MinValueValidator(0), MaxValueValidator(9999999)],
    )
    lit = models.IntegerField(
        blank=False,
        default=0,
        validators=[MinValueValidator(0), MaxValueValidator(9999999)],
    )
    pol = models.IntegerField(
        blank=False,
        default=0,
        validators=[MinValueValidator(0), MaxValueValidator(9999999)],
    )
    cadcam = models.IntegerField(
        blank=False,
        default=0,
        validators=[MinValueValidator(0), MaxValueValidator(9999999)],
    )
    gips = models.IntegerField(
        blank=False,
        default=0,
        validators=[MinValueValidator(0), MaxValueValidator(9999999)],
    )
    tech_st = models.IntegerField(
        blank=False,
        default=0,
        validators=[MinValueValidator(0), MaxValueValidator(9999999)],
    )

    class Meta:
        verbose_name = "Установка сотрудников на наряд"
        verbose_name_plural = "Установка сотрудников на наряд"

    def __str__(self) -> str:
        return f"""doc:{self.doc} tech:{self.tech} pol(36):{self.pol}
        lit(37):{self.lit} cad:{self.cadcam} gips:{self.gips} st:{self.tech_st}"""


kemerovo = timedelta(hours=7)


class Etaps(models.Model):
    naryad = models.ForeignKey(
        "It_lab",
        on_delete=models.CASCADE,
        null=True,
        blank=True,
        related_name="etaps",
    )
    etap = models.PositiveIntegerField(blank=True, null=True)
    dn = models.DateTimeField(auto_now=True, auto_now_add=False)
    dz = models.DateTimeField(blank=True, null=True)
    user = models.ForeignKey(MyUser, on_delete=models.DO_NOTHING, null=True, blank=True)
    sdl = models.ForeignKey(
        "Spr_sdl",
        on_delete=models.DO_NOTHING,
        null=True,
        blank=True,
    )

    class Meta:
        verbose_name = "Этапы выполнения наряда"
        verbose_name_plural = "Этапы выполнения наряда"

    def __str__(self) -> str:
        return f"{(self.dn + kemerovo).strftime("%d.%m.%Y %H:%M")}"


class Comments(models.Model):
    naryad = models.ForeignKey(
        "It_lab",
        on_delete=models.CASCADE,
        null=True,
        blank=True,
        related_name="comments",
    )
    date = models.DateTimeField(auto_now=True)
    user = models.ForeignKey(MyUser, on_delete=models.DO_NOTHING, null=True, blank=True)
    sdl = models.ForeignKey(
        "Spr_sdl",
        on_delete=models.DO_NOTHING,
        null=True,
        blank=True,
    )
    comment = models.TextField(blank=False)

    class Meta:
        verbose_name = "Этапы выполнения наряда"
        verbose_name_plural = "Этапы выполнения наряда"

    def __str__(self) -> str:
        return f"{(self.date + kemerovo).strftime("%d.%m.%Y %H:%M")}"


class Container(models.Model):
    used = models.BooleanField(
        default=False,
        verbose_name="Занят",
        help_text="Занятый контейнер не отображается в пустых",
    )
    nkv = models.CharField(max_length=50, default="", verbose_name="Номер наряда")

    def __str__(self) -> str:
        return f"{self.id}"

    def get_info(self) -> list[dict[str, Any]] | Literal[False] | None:
        if self.nkv :
            naryad: It_lab = It_lab.objects.get(nkv=self.nkv, id_etap=0)
            if naryad.dzr is not None or naryad.pdzr is not None:
                return False
            naryads = (
                It_lab.objects.filter(
                    container=self,
                    dzr__isnull=True,
                    pdzr__isnull=True,
                    id_etap__gt=0,
                )
                .select_related("user_etap_link")
                .order_by("nkv", "-id_etap")
                .distinct("nkv")
            )
            if naryads is None:
                return False

            nar = naryads.values(
                "nkv",
                "user_etap_link__fam",
                "user_etap_link__im",
                "user_etap_link__ot",
                "patient__fam",
                "patient__im",
                "patient__ot",
                "naryad_doc__user__fam",
                "naryad_doc__user__im",
                "naryad_doc__user__ot",
                "stu",
            )
            list_naryads = list(nar)
            for nar in list_naryads:
                if nar["user_etap_link__fam"] is None:
                    nar["user_etap_link__fam"] = "-"
                    nar["user_etap_link__im"] = "-"
                    nar["user_etap_link__ot"] = "-"
            return list_naryads
        return None


class It_lab(models.Model):  # noqa: N801
    lpu = models.ForeignKey(
        Spr_lpu,
        on_delete=models.PROTECT,
        blank=False,
        null=False,
        verbose_name="ЛПУ",
    )
    patient = models.ForeignKey(
        "Patient",
        on_delete=models.PROTECT,
        verbose_name="Пациент",
    )
    idkv = models.CharField(
        unique=True,
        blank=False,
        null=False,
        max_length=12,
        verbose_name="IDKV",
    )
    nkv = models.CharField(
        unique=True,
        blank=False,
        null=False,
        max_length=12,
        verbose_name="NKV",
    )
    dou = models.DateField(blank=False, null=False, verbose_name="Дата обращения")
    dzr = models.DateField(blank=True, null=True, verbose_name="Дата закрытия наряда")
    pdzr = models.DateField(blank=True, null=True, verbose_name="Предварительная ДЗР")
    check_zav = models.BooleanField(
        default=False,
        blank=False,
        null=False,
        verbose_name="Отметка Зав.",
    )
    check_tech = models.BooleanField(
        default=False,
        blank=False,
        null=False,
        verbose_name="Отметка Tex.",
    )
    status = models.PositiveIntegerField(blank=False, default=0, verbose_name="Статус")
    stu = models.DecimalField(
        blank=False,
        null=False,
        decimal_places=2,
        verbose_name="Стоимость",
        max_digits=10,
    )
    opl = models.ForeignKey(
        Spr_opl,
        on_delete=models.PROTECT,
        verbose_name="Тип оплаты",
    )
    id_etap = models.PositiveIntegerField(default=0, verbose_name="Номер этапа")
    dn_etap = models.DateField(
        auto_now=True, # Какую бы дату не писали проставится сегодня
        blank=True,
        null=True,
        verbose_name="Дата назначения этапа",
    )
    dz_etap = models.DateField(
        blank=True,
        null=True,
        verbose_name="Дата завершения этапа",
    )
    user_etap_link = models.ForeignKey(
        MyUser,
        on_delete=models.PROTECT,
        null=True,
        blank=True,
        verbose_name="Специалист этапа",
    )
    user_etap = models.CharField(
        max_length=40,
        blank=True,
        default="",
        verbose_name="Пользователь этапа",
    )
    naryad_doc = models.ForeignKey(
        "User_sdl",
        null=True,
        default=None,
        on_delete=models.PROTECT,
        verbose_name="Доктор наряда",
    )
    mpp_etap = models.PositiveIntegerField(
        blank=True,
        null=True,
        verbose_name="МПП этапа",
        validators=[MinValueValidator(0), MaxValueValidator(9999999)],
    )
    sdl_etap = models.ForeignKey(
        Spr_sdl,
        on_delete=models.PROTECT,
        verbose_name="Должность этапа",
    )
    sdl_set = models.ForeignKey(
        "Sdl_set",
        on_delete=models.PROTECT,
        blank=True,
        null=True,
        verbose_name="Ha6op должностей наряда",
    )
    container = models.ForeignKey(
        Container,
        verbose_name="Контейнер",
        on_delete=models.DO_NOTHING,
    )
    image_count = models.PositiveIntegerField(default=0)
    laboratory = models.BooleanField(default=False)
    profile_otd = models.PositiveIntegerField(default=2) # 2 - Ортопедия, 3 - Ортодонтия


    class Meta:
        verbose_name = "Наряды"
        verbose_name_plural = "Наряды"
        unique_together = ("nkv", "naryad_doc")

    def __str__(self) -> str:
        return f"{self.nkv}"

    def images_count(self) -> int:
        if self.id_etap == 0:
            return Images.objects.filter(naryad__nkv=self.nkv).count()
        return 0

    def get_doctor_fio(self) -> str:
        return (MyUser.objects.get(mpp=self.sdl_set.doc)).get_short_name()

    def current_spec_fio(self) -> str:
        if MyUser.objects.filter(mpp=self.mpp_etap).count() == 0:
            return "He назначен"
        return (MyUser.objects.get(mpp=self.mpp_etap)).get_short_name()

    def get_days(self) -> int:
        return (date.today() - self.dn_etap).days

    def get_days_done(self) -> int:
        return (self.dzr - self.dou).days if self.dzr else 0

    def money_for_doc(self) -> dict:
        dict_d = {}
        user = MyUser.objects.filter(mpp=self.sdl_set.doc).first()
        if user is None:
            return False
        dict_d["fio"] = user.fio
        dict_d["dolzh"] = "Врач"
        dict_d["mpp"] = self.sdl_set.doc
        if not self.laboratory:
            dict_d["lab_lgot"] = float(0)
            dict_d["lab_vt"] = float(0)
            dict_d["lab_pd"] = float(0)
            dict_d["lab_itog"] = float(0)
            dict_d["usl_lgot"] = self.sum_lgot
            dict_d["usl_vt"] = self.sum_vt
            dict_d["usl_pd"] = self.sum_pd
            dict_d["usl_itog"] = self.sum_itog
            return dict_d
        dict_d["lab_lgot"] = self.sum_lgot
        dict_d["lab_vt"] = self.sum_vt
        dict_d["lab_pd"] = self.sum_pd
        dict_d["lab_itog"] = self.sum_itog
        dict_d["usl_lgot"] = float(0)
        dict_d["usl_vt"] = float(0)
        dict_d["usl_pd"] = float(0)
        dict_d["usl_itog"] = float(0)
        return dict_d

    def money_for_tech(self) -> dict:
        try:
            if not self.laboratory:
                return False
            user = MyUser.objects.filter(mpp=self.sdl_set.tech).first()
            if user is None:
                return False
            dict_d = {}
            dict_d["fio"] = user.fio
            dict_d["dolzh"] = "Зубной техник"
            dict_d["mpp"] = user.mpp
            dict_d["lab_lgot"] = self.sum_lgot
            dict_d["lab_vt"] = self.sum_vt
            dict_d["lab_pd"] = self.sum_pd
            dict_d["lab_itog"] = self.sum_itog
        except MyUser.DoesNotExist:
            logging.exception("MyUser Not find fot tech money")
        else:
            return dict_d

    def money_for_pol(self) -> dict:
        try:
            if not self.laboratory:
                return False
            user = MyUser.objects.filter(mpp=self.sdl_set.pol).first()
            if user is None:
                return False
            dict_d = {}
            dict_d["fio"] = user.fio
            dict_d["dolzh"] = "Полировщик"
            dict_d["mpp"] = user.mpp
            dict_d["lab_lgot"] = self.sum_lgot
            dict_d["lab_vt"] = self.sum_vt
            dict_d["lab_pd"] = self.sum_pd
            dict_d["lab_itog"] = self.sum_itog
        except MyUser.DoesNotExist:
            logging.exception("MyUser Not find fot pol money")
        else:
            return dict_d

    def money_for_lit(self) -> dict:
        try:
            if not self.laboratory:
                return False
            user = MyUser.objects.filter(mpp=self.sdl_set.lit).first()
            if user is None:
                return False
            dict_d = {}
            dict_d["fio"] = user.fio
            dict_d["dolzh"] = "Литейщик"
            dict_d["mpp"] = user.mpp
            dict_d["lab_lgot"] = self.sum_lgot
            dict_d["lab_vt"] = self.sum_vt
            dict_d["lab_pd"] = self.sum_pd
            dict_d["lab_itog"] = self.sum_itog
        except MyUser.DoesNotExist:
            logging.exception("MyUser Not find fot lit money")
        else:
            return dict_d

    def money_for_cadcam(self) -> dict:
        try:
            if not self.laboratory:
                return False
            user = MyUser.objects.filter(mpp=self.sdl_set.cadcam).first()
            if user is None:
                return False
            dict_d = {}
            dict_d["fio"] = user.fio
            dict_d["dolzh"] = "Оператор Cad/Cam"
            dict_d["mpp"] = user.mpp
            dict_d["lab_lgot"] = self.sum_lgot
            dict_d["lab_vt"] = self.sum_vt
            dict_d["lab_pd"] = self.sum_pd
            dict_d["lab_itog"] = self.sum_itog
        except MyUser.DoesNotExist:
            logging.exception("MyUser Not find fot cadcam money")
        else:
            return dict_d

    def zp_for_tech(self) -> dict:
        if not self.laboratory:
            return False
        user = MyUser.objects.filter(mpp=self.sdl_set.tech).first()
        if user is None:
            return False
        dict_d = {}
        dict_d["fio"] = user.fio
        dict_d["dolzh"] = "Зубной техник"
        dict_d["mpp"] = user.mpp
        dict_d["lab_lgot"] = self.tech_zp_lgot
        dict_d["lab_vt"] = self.tech_zp_vt
        dict_d["lab_pd"] = self.tech_zp_pd
        dict_d["lab_itog"] = self.tech_zp_itog
        return dict_d

    def zp_for_pol(self) -> dict:
        if not self.laboratory:
            return False
        user = MyUser.objects.filter(mpp=self.sdl_set.pol).first()
        if user is None:
            return False
        dict_d = {}
        dict_d["fio"] = user.fio
        dict_d["dolzh"] = "Полировщик"
        dict_d["mpp"] = user.mpp
        dict_d["lab_lgot"] = self.pol_zp_lgot
        dict_d["lab_vt"] = self.pol_zp_vt
        dict_d["lab_pd"] = self.pol_zp_pd
        dict_d["lab_itog"] = self.pol_zp_itog
        return dict_d

    def zp_for_lit(self) -> dict:
        if not self.laboratory:
            return False
        user = MyUser.objects.filter(mpp=self.sdl_set.lit).first()
        if user is None:
            return False
        dict_d = {}
        dict_d["fio"] = user.fio
        dict_d["dolzh"] = "Литейщик"
        dict_d["mpp"] = user.mpp
        dict_d["lab_lgot"] = self.lit_zp_lgot
        dict_d["lab_vt"] = self.lit_zp_vt
        dict_d["lab_pd"] = self.lit_zp_pd
        dict_d["lab_itog"] = self.lit_zp_itog
        return dict_d

    def zp_for_cadcam(self) -> dict:
        if not self.laboratory:
            return False
        user = MyUser.objects.filter(mpp=self.sdl_set.cadcam).first()
        if user is None:
            return False
        dict_d = {}
        dict_d["fio"] = user.fio
        dict_d["dolzh"] = "Оператор Cad/Cam"
        dict_d["mpp"] = user.mpp
        dict_d["lab_lgot"] = self.cadcam_zp_lgot
        dict_d["lab_vt"] = self.cadcam_zp_vt
        dict_d["lab_pd"] = self.cadcam_zp_pd
        dict_d["lab_itog"] = self.cadcam_zp_itog
        return dict_d

    @property
    def sum_lgot(self) -> float:
        summa = Decimal("0")
        usls = Pl_uslp.objects.filter(naryad=self)
        for usl in usls:
            if usl.kusl.startswith("Л"):
               summa += usl.stu
        return float(summa)

    @property
    def sum_vt(self) -> float:
        summa = Decimal("0")
        usls = Pl_uslp.objects.filter(naryad=self)
        for usl in usls:
            if usl.kusl.startswith("2.8"):
               summa += usl.stu
        return float(summa)

    @property
    def sum_pd(self) -> float:
        summa = Decimal("0")
        usls = Pl_uslp.objects.filter(naryad=self)
        for usl in usls:
            if not usl.kusl.startswith("2.8") and not usl.kusl.startswith("Л"):
               summa += usl.stu
        return float(summa)

    @property
    def sum_itog(self) -> float:
        summa = Decimal("0")
        usls = Pl_uslp.objects.filter(naryad=self)
        for usl in usls:
            summa += usl.stu
        return float(summa)

    @property
    def tech_zp_lgot(self) -> float:
        summa = Decimal("0")
        usls = Pl_uslp.objects.filter(naryad=self)
        for usl in usls:
            if usl.kusl.startswith("Л"):
                summa += usl.tech
        return float(summa)

    @property
    def tech_zp_vt(self) -> float:
        summa = Decimal("0")
        usls = Pl_uslp.objects.filter(naryad=self)
        for usl in usls:
            if usl.kusl.startswith("2.8"):
                summa += usl.tech
        return float(summa)

    @property
    def tech_zp_pd(self) -> float:
        summa = Decimal("0")
        usls = Pl_uslp.objects.filter(naryad=self)
        for usl in usls:
            if not usl.kusl.startswith("2.8") and not usl.kusl.startswith("Л"):
                summa += usl.tech
        return float(summa)

    @property
    def tech_zp_itog(self) -> float:
        summa = Decimal("0")
        usls = Pl_uslp.objects.filter(naryad=self)
        for usl in usls:
            summa += usl.tech
        return float(summa)

    @property
    def pol_zp_lgot(self) -> float:
        summa = Decimal("0")
        usls = Pl_uslp.objects.filter(naryad=self)
        for usl in usls:
            if usl.kusl.startswith("Л"):
                summa += usl.pol
        return float(summa)

    @property
    def pol_zp_vt(self) -> float:
        summa = Decimal("0")
        usls = Pl_uslp.objects.filter(naryad=self)
        for usl in usls:
            if usl.kusl.startswith("2.8"):
                summa += usl.pol
        return float(summa)

    @property
    def pol_zp_pd(self) -> float:
        summa = Decimal("0")
        usls = Pl_uslp.objects.filter(naryad=self)
        for usl in usls:
            if not usl.kusl.startswith("2.8") and not usl.kusl.startswith("Л"):
                summa += usl.pol
        return float(summa)

    @property
    def pol_zp_itog(self) -> float:
        summa = Decimal("0")
        usls = Pl_uslp.objects.filter(naryad=self)
        for usl in usls:
            summa += usl.pol
        return float(summa)

    @property
    def lit_zp_lgot(self) -> float:
        summa = Decimal("0")
        usls = Pl_uslp.objects.filter(naryad=self)
        for usl in usls:
            if usl.kusl.startswith("Л"):
                summa += usl.lit
        return float(summa)

    @property
    def lit_zp_vt(self) -> float:
        summa = Decimal("0")
        usls = Pl_uslp.objects.filter(naryad=self)
        for usl in usls:
            if usl.kusl.startswith("2.8"):
                summa += usl.lit
        return float(summa)

    @property
    def lit_zp_pd(self) -> float:
        summa = Decimal("0")
        usls = Pl_uslp.objects.filter(naryad=self)
        for usl in usls:
            if not usl.kusl.startswith("2.8") and not usl.kusl.startswith("Л"):
                summa += usl.lit
        return float(summa)

    @property
    def lit_zp_itog(self) -> float:
        summa = Decimal("0")
        usls = Pl_uslp.objects.filter(naryad=self)
        for usl in usls:
            summa += usl.lit
        return float(summa)

    @property
    def cadcam_zp_lgot(self) -> float:
        summa = Decimal("0")
        usls = Pl_uslp.objects.filter(naryad=self)
        for usl in usls:
            if usl.kusl.startswith("Л"):
                summa += usl.cadcam
        return float(summa)

    @property
    def cadcam_zp_vt(self) -> float:
        summa = Decimal("0")
        usls = Pl_uslp.objects.filter(naryad=self)
        for usl in usls:
            if usl.kusl.startswith("2.8"):
                summa += usl.cadcam
        return float(summa)

    @property
    def cadcam_zp_pd(self) -> float:
        summa = Decimal("0")
        usls = Pl_uslp.objects.filter(naryad=self)
        for usl in usls:
            if not usl.kusl.startswith("2.8") and not usl.kusl.startswith("Л"):
                summa += usl.cadcam
        return float(summa)

    @property
    def cadcam_zp_itog(self) -> float:
        summa = Decimal("0")
        usls = Pl_uslp.objects.filter(naryad=self)
        for usl in usls:
            summa += usl.cadcam
        return float(summa)

    @admin.display
    def admin_link(self) -> SafeText:
        return format_html(
           '<a href="{}/{}">{}</a>',
            "http://192.168.100.61:3000/admin/changespec",
            # "http://localhost:3000/admin/changespec",
            self.nkv,
            self.nkv,
        )


class Pl_uslp(models.Model):  # noqa: N801
    idkv = models.CharField(max_length=12, blank=False, null=False)
    naryad = models.ForeignKey(It_lab, verbose_name="Наряд", on_delete=models.CASCADE, related_name="uslugi", default=1)
    kusl = models.CharField(max_length=50, blank=False, null=False)
    usl = models.PositiveIntegerField(blank=False, null=False)
    nusl = models.CharField(max_length=200, blank=False, null=False)
    kol = models.PositiveIntegerField(blank=False, null=False)
    uet = models.FloatField()
    price = models.DecimalField(max_digits=10, decimal_places=2)
    stu = models.GeneratedField(expression=F("price") * F("kol"), output_field=models.DecimalField(max_digits=10, decimal_places=2), db_persist=True)
    tech = models.DecimalField(max_digits=10, decimal_places=2, default=0.0)
    pol = models.DecimalField(max_digits=10, decimal_places=2, default=0.0)
    lit = models.DecimalField(max_digits=10, decimal_places=2, default=0.0)
    cadcam = models.DecimalField(max_digits=10, decimal_places=2, default=0.0)
    gips = models.DecimalField(max_digits=10, decimal_places=2, default=0.0)

    class Meta:
        verbose_name = "Услуги"
        verbose_name_plural = "Услуги"

    def __str__(self) -> str:
        return f"{self.naryad.nkv}, {self.kusl}, {self.stu}"


class Patient(Base):
    uid = models.PositiveIntegerField(blank=False, null=False, default=9999999)
    fam = models.CharField(max_length=40, blank=False, null=False)
    im = models.CharField(max_length=40, blank=False, null=False)
    ot = models.CharField(max_length=40, blank=True, default="")
    dr = models.DateField(blank=False, null=False, default=timezone.now)
    adress = models.CharField(max_length=100, blank=True, default="")

    class Meta:
        verbose_name = "Пациенты"
        verbose_name_plural = "Пациенты"

    def __str__(self) -> str:
        return f"{self.fam} {self.im} {self.ot}"

    def cut_fio(self) -> str:
        return f"{self.fam} {self.im[0]}. {self.ot[0]}."


class Zav_report(Base):  # noqa: N801
    mpp = models.PositiveIntegerField(null=False, blank=False)
    year = models.PositiveIntegerField(null=False, blank=False)
    month = models.PositiveIntegerField(null=False, blank=False)
    dn = models.CharField(max_length=50)
    dk = models.CharField(max_length=50)
    opl = models.JSONField()
    kol_lab = models.PositiveIntegerField(null=True, blank=True)
    kol_usl = models.PositiveIntegerField(null=True, blank=True)
    kol_all = models.PositiveIntegerField(null=False, blank=False)
    stu_lab = models.DecimalField(max_digits=10, decimal_places=2)
    stu_usl = models.DecimalField(max_digits=10, decimal_places=2)
    stu_all = models.DecimalField(max_digits=10, decimal_places=2)
    nars_lab = models.JSONField()
    nars_usl = models.JSONField()
    nars_lab_cancel = models.JSONField()
    nars_usl_cancel = models.JSONField()

    class Meta:
        verbose_name = "Закрытия периодов"
        verbose_name_plural = "Закрытия периодов"

    def __str__(self) -> str:
        return f"{self.mpp}, {self.month}, {self.opl}"


class Zav_pdr(models.Model):  # noqa: N801
    mpp = models.PositiveIntegerField(null=False, blank=False)
    years = models.PositiveIntegerField(null=False, blank=False)
    months = models.PositiveIntegerField(null=False, blank=False)
    opl = models.JSONField()
    kol_lab = models.PositiveIntegerField(null=True, blank=True)
    kol_usl = models.PositiveIntegerField(null=True, blank=True)
    kol_all = models.PositiveIntegerField(null=False, blank=False)
    stu_lab = models.DecimalField(max_digits=10, decimal_places=2)
    stu_usl = models.DecimalField(max_digits=10, decimal_places=2)
    stu_all = models.DecimalField(max_digits=10, decimal_places=2)
    nars_lab = models.JSONField()
    nars_usl = models.JSONField()
    nars_lab_approved = models.JSONField()
    nars_usl_approved = models.JSONField()
    nars_lab_cancel = models.JSONField()
    nars_usl_cancel = models.JSONField()
    log = models.TextField()

    def __str__(self) -> str:
        return f"{self.mpp}, {self.opl}, {self.months}"


class Spr_access(Base):  # noqa: N801
    access = models.CharField(
        max_length=50,
        blank=False,
        null=False,
        verbose_name="Доступ (латиница)",
    )
    access_name = models.CharField(
        max_length=50,
        blank=False,
        null=False,
        verbose_name="Расшифровка (русский)",
    )

    class Meta:
        verbose_name = "Права доступа"
        verbose_name_plural = "Права доступа"

    def __str__(self) -> str:
        return f"{self.access_name}"


class User_sdl(Base):  # noqa: N801
    user = models.ForeignKey(
        MyUser,
        on_delete=models.CASCADE,
        verbose_name="Пользователь",
    )
    doc = models.PositiveIntegerField(null=True, default=0, verbose_name="Код из 1С")
    sdls = models.ManyToManyField(Spr_sdl, verbose_name="Должность")
    access = models.ManyToManyField(Spr_access, verbose_name="Доступ")
    lpu = models.ForeignKey(Spr_lpu, on_delete=models.CASCADE, verbose_name="ЛПУ")

    class Meta:
        verbose_name = "Сотрудники"
        verbose_name_plural = "Сотрудники"

    def __str__(self) -> str:
        str_out = f"{self.user.fam} {self.user.im} {self.user.ot}"
        for i, sdl in enumerate(specialization(self.user)):
            if i == 0:
                str_out += " - "
            str_out += f"{sdl.name_sdl}"
            if i < len(specialization(self.user)) - 1:
                str_out += ", "
        return str_out

    def fio(self) -> str:
        return f"{self.user.fam} {self.user.im} {self.user.ot}"

    def fio_short(self) -> str:
        return f"{self.user.fam} {self.user.im[0]}. {self.user.ot[0]}."

    def users(self) -> MyUser:
        return self.user

    def fam(self) -> str:
        return self.user.fam

    @property
    def dolzh(self) -> LiteralString:
        return ", ".join([x.name_sdl for x in specialization(self.user)])

    def sdl_list(self) -> list:
        return [x.sdl for x in self.sdls.all()]

    def access_list(self) -> list:
        return [x.access for x in self.access.all().distinct()]

    @classmethod
    def access2(cls) -> list:
        return [x.access for x in cls.access.all().distinct()]

    fio.short_description = "ФИО"
    fam.short_description = "Фамилия"


def specialization(user: MyUser) -> list:
    list_sdl = []
    for i in User_sdl.objects.filter(user=user):
        for j in i.sdls.all():
            list_sdl.append(j)  # noqa: PERF402
    return list_sdl


class Kadr_sdl(Base):  # noqa: N801
    sdls = models.ManyToManyField(MyUser, through="Kadr_sdl_connect")

    def __str__(self) -> str:
        return f"""
    {self.sdls.first().fam} {self.sdls.first().im} {Kadr_sdl_connect.objects.filter(user=self.sdls.all()[0])[0].spec}"""


class Kadr_sdl_connect(Base):  # noqa: N801
    user = models.ForeignKey(MyUser, on_delete=models.CASCADE)
    sdl = models.ForeignKey(Spr_sdl, on_delete=models.CASCADE)
    kadr_sdl = models.ForeignKey(Kadr_sdl, on_delete=models.CASCADE)

    def __str__(self) -> str:
        return f"{self.user} {self.sdl}"

    def spec(self) -> list[str]:
        return [x.sdl.name_sdl for x in Kadr_sdl_connect.objects.filter(user=self.user)]


class Buhreport(Base):
    year = models.PositiveIntegerField()
    month = models.PositiveIntegerField()
    podr = models.PositiveIntegerField(default=0)
    profile = models.PositiveIntegerField(default=2)
    list_docs = models.JSONField(default=list)
    list_techs = models.JSONField(default=list)
    list_pols = models.JSONField(default=list)
    list_lits = models.JSONField(default=list)
    list_cadcams = models.JSONField(default=list)
    list_zp_techs = models.JSONField(default=list)
    list_zp_pols = models.JSONField(default=list)
    list_zp_lits = models.JSONField(default=list)
    list_zp_cadcams = models.JSONField(default=list)
    file = models.FileField(upload_to="buhreps/%Y/%m/", blank=True, null=True)

    def __str__(self) -> str:
        return f"{self.year}, {self.month}"

class Mpp_podr(Base):  # noqa: N801
    # Проебался, на самом деле в mpp лежит MyUser, нет времени делать миграцию.
    mpp = models.OneToOneField(
        MyUser,
        blank=False,
        null=False,
        verbose_name="Пользователь",
        on_delete=models.CASCADE,
    )
    podr = models.JSONField(null=True, verbose_name="Подразделения")

    def __str__(self) -> str:
        return f"{self.mpp.fam} - {len(self.podr)} подразделений"


class Images(models.Model):
    etap = models.ForeignKey(
        It_lab,
        default=None,
        related_name="images",
        on_delete=models.CASCADE,
        verbose_name="Этап",
    )
    naryad = models.CharField(default="", max_length=12, verbose_name="Номер наряда")
    img = models.ImageField(
        upload_to="photos/%Y/%m/%d/",
        blank=True,
        null=False,
        verbose_name="Фото",
    )
    user_mpp = models.PositiveIntegerField(default=0, verbose_name="Пользователь")

    class Meta:
        verbose_name = "Изображения"
        verbose_name_plural = "Изображения"

    def __str__(self) -> str:
        return f"{self.naryad}"

    def thumbnail(self) -> str:
        return f'<img src="{self.img.url}" />'

    thumbnail.short_description = "Thumbnail"


# AUDITLOG_INCLUDE_ALL_MODELS=True


# auditlog.register(It_lab, serialize_data=True)
# auditlog.register(Spr_opl, serialize_data=True)
# auditlog.register(Spr_sdl, serialize_data=True)
# auditlog.register(Spr_lab, serialize_data=True)
# auditlog.register(Spr_lpu, serialize_data=True)
# auditlog.register(Sdl_set, serialize_data=True)
# auditlog.register(Etaps, serialize_data=True)
# auditlog.register(Comments, serialize_data=True)
# auditlog.register(Container, serialize_data=True)
# auditlog.register(Pl_uslp, serialize_data=True)
# auditlog.register(Patient, serialize_data=True)
# auditlog.register(Zav_report, serialize_data=True)
# auditlog.register(Zav_pdr, serialize_data=True)
# auditlog.register(Spr_access, serialize_data=True)
# auditlog.register(User_sdl, serialize_data=True)
# auditlog.register(Kadr_sdl, serialize_data=True)
# auditlog.register(Kadr_sdl_connect, serialize_data=True)
# auditlog.register(Mpp_podr, serialize_data=True)
# auditlog.register(Images, serialize_data=True)
